<template>
  <div flex style="height: 100%;">

    <div v-if="oGraph">
      <Teleport to='#mp-resource'>
        <div flex flex-col h="100%">
          <MyBar>
            <div>局部变量({{ oGraph?.name }})</div>
          </MyBar>
          <div 局部变量列表 flex-1>
            <div v-for="item in oGraph.locals" class="my-action" p4 bg="#ffffff10" hover-bg="#ffffff20"
              b-b="1px solid #ffffff20" flex items-center @dblclick="oBus.editLocal(item)">
              <div>{{ item.name }}</div>
              <ContextMenu title="变量" :context="item" :menu-items="[
                {
                  icon: ElIconEdit,
                  title: '修改声明',
                  action: () => {
                    oBus.editLocal(item)
                    return true
                  }
                },
                {
                  icon: ElIconDelete,
                  title: '删除',
                  action: (c) => {
                    deleteLocal(c)
                    return true
                  }
                },
              ]" />
            </div>
            <ContextMenu title="新建" :context="null" :menu-items="[
              {
                title: '局部变量',
                action: () => {
                  oBus.editLocal()
                  return true
                }
              }]" />
          </div>
        </div>

      </Teleport>
    </div>

    <div flex-1>
      <div v-if="!oGraph" h="100%" w="100%" flex items-center justify-center text-gray text-size-6>
        请选择动作
      </div>
      <div v-else flex flex-col h="100%">
        <MyBar>
          <div v-if="!renaming" @mouseenter="showRename = true" @mouseleave="showRename = false" flex items-center>
            <div mr2>{{ oGraph.name }}</div>
            <el-button size="small" type="warning" plain v-show="showRename"
              @click="renaming = true; showRename = false">重命名</el-button>
          </div>
          <div v-if="renaming" flex items-center>
            <el-input size="small" v-model:model-value="oGraph.name" style="width: 120px;"
              @keydown.enter="renaming = false" />
            <el-button ml type="primary" plain size="small" @click="renaming = false">确定</el-button>
          </div>
          <button class="my-button" @click="graphCompile" ml-auto>编译</button>
          <button class="my-button" @click="graphTest" ml2>测试</button>
        </MyBar>
        <!-- <div style="background: var(--bg-builtin);" px4 h="3rem" flex items-center>

        </div> -->
        <GraphDisplay flex-1 :graph="oGraph" />
        <Logger />
      </div>
    </div>

  </div>
</template>

<script setup lang="ts">
import { useLocalStorage } from '@vueuse/core';
import { shell } from '~/models/Logger';
import { defaultTaskManager } from '~/models/Task/TaskManager';
import { oBus } from '~/models/graph/editorbus';
import { oGraph, Graph } from '~/models/graph/graph';
import { oProject, oStorage } from '~/models/Project';
import type { VarInit } from "~/models/data/var_init";
import { tNum } from '~/models/types';
import { PNode } from '~/models/graph/node/prototype';
import { PNodeType } from '~/models/graph/node/type';
import { Compiler } from '~/models/compile/AstCompiler';
import { GraphCompiler } from '~/models/compile/GraphCompiler';

// ui
const showRename = ref(false)
const renaming = ref(false)
const graphs = computed(() => oProject.value!.storage.graphs)

const openIndex = useLocalStorage('actions-openIndex', -1)
function chooseScript(index: number) {
  const script = graphs.value[index]
  oGraph.value = script
  openIndex.value = index
}

const route = useRoute()
function loadByRoute() {
  const id = route.query.id
  const script = graphs.value.find(x => x.id === id)
  // console.log(script);
  if (script) {
    oGraph.value = script
  }
}
onMounted(() => {
  loadByRoute()
})

watch(() => route.query, (val) => {
  loadByRoute()
})


/** 函数: 编译 */
async function graphCompile() {
  if (oGraph.value) {
    const code = GraphCompiler.compile(oGraph.value)
    shell.success(code, '编译结果')
  }
}

/** 函数: 运行测试 */
async function graphTest() {
  if (oGraph.value) {

    // 检查是不是有参数
    if (oGraph.value.params.length !== 0) {
      shell.error(`函数具有参数，不能作为程序起点`)
      return
    }

    const code = GraphCompiler.compile(oGraph.value)
    const result = await defaultTaskManager.value.execRaw(code, true)
    if (result.success) {
      const message = JSON.parse(result.message!)
      console.log(message);

      message.logs.forEach((log: any) => {
        shell.debug(log, '调试输出')
      })
      if (message.logs.length > 0 && message.value === null) {
        // 有调试输出，没有结果就跳过输出结果
        return
      }
      logReturn(message.value)
      console.log(message.value);

    }
    else {
      shell.error(result.message ? `运行时发生异常: ${result.message}` : '无错误信息')
    }
  }
}

/** 函数运行测试: 输出结果 */
function logReturn(ret: any) {
  if (ret === null) {
    shell.success('程序无返回值')
  }
  else if (Object.prototype.toString.call(ret) === '[object Array]') {
    (ret as any[]).forEach(x => logReturn(x))
  }
  else {
    shell.success(`程序返回值: ${ret}`)
  }
}

/** 局部变量: 删除 */
function deleteLocal(item: VarInit) {
  if (!oGraph.value) {
    throw new Error('!oGraph.value')
  }
  // 找到对应的getter/setter，断连,移除
  const gsb = PNode.getterFromTGD(item)
  const ssb = PNode.setterFromTGD(item)
  const dropList = oGraph.value.nodes.filter(node => {
    return (
      node.prototype.name === item.name
      && [PNodeType.Getter, PNodeType.Setter].includes(node.prototype.type)
    )
  })
  dropList.forEach(node => node.slots.forEach(slot => slot.disconnect()))
  dropList.forEach(node => remove(oGraph.value!.nodesId, x => x === node.id))
  remove(oGraph.value.locals, x => x === item)
}
</script>